/***************************************************************************
* Lyrics-Player                                                            *
* Copyright (C) 2012 Andrey Derevyanko <derandr@gmail.com>                 *
*                                                                          *
* This program is free software: you can redistribute it and/or modify     *
* it under the terms of the GNU General Public License as published by     *
* the Free Software Foundation, either version 3 of the License, or        *
* (at your option) any later version.                                      *
*                                                                          *
* This program is distributed in the hope that it will be useful,          *
* but WITHOUT ANY WARRANTY; without even the implied warranty of           *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
* GNU General Public License for more details.                             *
*                                                                          *
* You should have received a copy of the GNU General Public License        *
* along with this program.  If not, see <http://www.gnu.org/licenses/>.    *
***************************************************************************/

/*! \file trackRecModel.h
 *  \brief Tracks data model
 *  \details Provides tracks information and their play by Phonon mechanism
 *  \author Andrey Derevyanko <derandr@gmail.com>
 *  \version 1.1
 *  \date 10/10/2012
 *  \copyright GNU Public License
 */

#ifndef __TRACK_REC_MOD__
#define __TRACK_REC_MOD__

#include <QAbstractListModel>
#include <QString>
#include <QList>
#include <QMessageBox>
#include <QTextStream>
#include <QFile>
#include <QDebug>
#include <QDir>
#include <QTime>
#include <QStringList>
#include <QTimer>

#include <phonon/mediaobject.h>

#include "trackRecord.h"
#include "processThread.h"
#include "sharedStructures.h"

#include "id3Lib.h"

/*! \class TrackRecordModel
 *  \brief Model of the class that stored track information
 */
class TrackRecordModel : public QAbstractListModel
{
Q_OBJECT
public:
    /*! \enum gotoTrack
     *  \brief Next track selection variants
     */
    enum gotoTrack
    {
        firstTrack, //!< First track
        lastTrack, //!< Last track
        nextTrack, //!< Next track
        prevTrack, //!< Previous track
        randTrack //!< Random track
    };
    //! Default constructor
    TrackRecordModel();
    //! Destructor
    ~TrackRecordModel();
    /*! \fn QVariant data(const QModelIndex &index, int role) const
     *  \brief Table data
     *  \param index Needed cell coordinates
     *  \param role Needed cell role
     *  \return Cell data
     */
    QVariant data(const QModelIndex &index, int role) const;
    /*! \fn int rowCount(const QModelIndex &parent = QModelIndex()) const;
     *  \brief Row count
     *  \param parent Parent widget
     *  \return Tracks number in the list
     */
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    /*! \fn QVariant headerData(int section, Qt::Orientation orientation, int role) const;
     *  \brief Table header
     *  \param section Header coordinates
     *  \param orientation If the header top or side
     *  \param role Cell role
     *  \return Cell data
     */
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    /*! \fn Phonon::MediaObject * mediaObject()
     *  \brief Get the pointer to the playing object
     *  \return Pointer to the actual Phonon::MediaObject.
     */
    Phonon::MediaObject * mediaObject();
    /*! \fn int addTrack(QString sFilePath)
     *  \brief Add track to the list
     *  \param sFilePath Mediafile path
     *  \return Track numer in the list
     */
    int addTrack(QString sFilePath);
    /*! \fn void playLast()
     *  \brief Play the last track from the list
     *  \details Function is called when the program is launched with a parameter. In this case
     *  the file is added to the end and play queue starts with it
     */
    void playLast();
    /*! \fn void playFirst()
     *  \brief Play first track
     */
    void playFirst();
    /*! \fn void ssPlay()
     *  \brief Start playing
     */
    void ssPlay();
    /*! \fn void ssPause()
     *  \brief Pause playing
     */
    void ssPause();
    /*! \fn void ssStop()
     *  \brief Stop playing
     */
    void ssStop();
    /*! \fn void saveModel(QString fileName = "default.spl")
     *  \brief Save the actual list to file
     *  \param fileName File name to save
     */
    void saveModel(QString fileName = "default.spl");
    /*! \fn void loadModel(QString fileName = "default.spl")
     *  \brief Load track list from file
     *  \param fileName File name to load
     */
    void loadModel(QString fileName = "default.spl");
    /*! \fn void newTrack2Play(gotoTrack)
     *  \brief Go to track
     *  \param gotoTrack Swithing variant
     */
    void newTrack2Play(gotoTrack);
    /*! \fn bool getRandomPlay()
     *  \brief If random play is turned on
     *  \return Random mode
     */
    bool getRandomPlay();
    /*! \fn void setRandomPlay(bool bRnd)
     *  \brief Set random mode
     *  \param bRnd Random state
     */
    void setRandomPlay(bool bRnd);
private:
    Phonon::MediaObject * playMedia; //!< Pointer to the actual selected file
    QList<trackRecord> trackList; //!< List of the structures that desctibes tracks
    processThread nameThread; //!< Thread that changes filenames to descriptions Artist - Song
    bool isRandomPlay; //!< Is the playing random
    bool isPaused; //!< Is the actual atete is pause one
    quint16 selectRow; //!< Selected file for highlighting
    quint16 playRow; //!< Playing file for highlighting
    trackMetaData_t trackMetaData; //!< Track meta data
    QTimer mDataProcTimer; //!< Timer for metadata process error elimination
    id3Lib::id3Reader *metaDataReader;
    id3Lib::id3Writer *metaDataWriter;
public slots:
    /*! \fn void fileSelect(const QModelIndex & index)
     *  \brief Select file for lyrics view
     *  \param index New file coordinates
     */
    void fileSelect(const QModelIndex & index);
    /*! \fn void playThis(const QModelIndex & index)
     *  \brief Select file to play
     */
    void playThis();
    /*! \fn void playPrevTrack()
     *  \brief Switch to the previous track
     */
    void playPrevTrack();
    /*! \fn void playNextTrack()
     *  \brief Switch to the next track
     */
    void playNextTrack();
    /*! \fn void updateMe()
     *  \brief Update model
     */
    void updateMe();
    /*! \fn void getTotalTime(qint64)
     *  \brief Get new full time
     */
    void getTotalTime(qint64);
    /*! \fn void getCurrentTime(qint64)
     *  \brief Get new actual time
     */
    void getCurrentTime(qint64);
    /*! \fn void fileRemove()
     *  \brief Remove currently selected file from the list
     */
    void fileRemove();
    /*! \fn void clearList()
     *  \brief Clear track list
     */
    void clearList();
    /*! \fn void toggleRandomPlay()
     *  \brief Toggle state of random play
     */
    void toggleRandomPlay() {isRandomPlay = !isRandomPlay;}
    /*! \fn void trackDataReady()
     *  \brief Metadata are ready to be read from metaDataMedia
     */
    void trackDataReady();
    /*! \fn void trackID3DataReady(trackMetaData_t data)
     *  \brief Metadata from id3 library is ready
     *  \param data Structure containing metadata
     */
    void trackID3DataReady(trackMetaData_t data);
    /*! \fn void trackDataTimeOut()
     *  \brief Metadata are not ready in a pre-defined period of time
     *  \see max_proc_time
     */
    void trackDataTimeOut();
    /*! \fn void newEditedMetaData(trackMetaData_t data)
     *  \brief Saving edited metadata using id3 accesser
     *  \param data Structure containing metadata
     */
    void newEditedMetaData(trackMetaData_t data);
signals:
    /*! \fn void lyricsAvailable(const QString lyrFileString)
     *  \brief Lyrics is available
     *  \param lyrFileString Path to the file with lyrics
     */
    void lyricsAvailable(const QString lyrFileString);
    /*! \fn void newTotalTime(qint64)
     *  \brief Send new full time
     */
    void newTotalTime(qint64);
    /*! \fn void newCurrentTime(qint64)
     *  \brief Send new actual time
     */
    void newCurrentTime(qint64);
    /*! \fn void newTrackName(QString)
     *  \brief Send track name
     */
    void newTrackName(QString);
    /*! \fn void newFileInfo(trackMetaData_t)
     *  \brief Send file meta data
     *  \param data Structure containing metadata
     */
    void newFileInfo(trackMetaData_t data);
    /*! \fn void newFileName(QString fileName)
     *  \brief Full file name of the selected file
     *  \param fileName File name in the file system
     */
    void newFileName(QString fileName);
    /*! \fn void newMetaDataToSave(QString fileName, trackMetaData_t data)
     *  \brief Metadata were edited and are sent to id3 writer
     *  \param fileName File name in the file system
     *  \param data Structure containing metadata
     */
    void newMetaDataToSave(QString fileName, trackMetaData_t data);
    /*! \fn void newPlayIcon(playState_t state)
     *  \brief Action was done and icon should be changed
     *  \param state New state
     */
    void newPlayIcon(playState_t state);
};

#endif
